package com.yupi.yuoj.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.yuoj.annotation.AuthCheck;
import com.yupi.yuoj.common.BaseResponse;
import com.yupi.yuoj.common.DeleteRequest;
import com.yupi.yuoj.common.ErrorCode;
import com.yupi.yuoj.common.ResultUtils;
import com.yupi.yuoj.constant.UserConstant;
import com.yupi.yuoj.exception.BusinessException;
import com.yupi.yuoj.exception.ThrowUtils;
import com.yupi.yuoj.model.entity.ContestQuestion;
import com.yupi.yuoj.service.ContestQuestionService;
import com.yupi.yuoj.service.UserService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.List;

/**
 * 竞赛题目接口
 *
 * @author yupi
 */
@RestController
@RequestMapping("/contest-question")
@Slf4j
public class ContestQuestionController {

    @Resource
    private ContestQuestionService contestQuestionService;

    @Resource
    private UserService userService;

    // region 增删改查

    /**
     * 创建竞赛题目关联
     *
     * @param contestQuestion
     * @param request
     * @return
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> addContestQuestion(@RequestBody ContestQuestion contestQuestion, HttpServletRequest request) {
        if (contestQuestion == null || contestQuestion.getQuestionId() == null || contestQuestion.getQuestionId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        // 检查是否已存在相同的关联
        ContestQuestion existingRelation = contestQuestionService.lambdaQuery()
                .eq(ContestQuestion::getContestId, contestQuestion.getContestId())
                .eq(ContestQuestion::getQuestionId, contestQuestion.getQuestionId())
                .one();
        if (existingRelation != null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "竞赛题目关联已存在");
        }
        
        boolean result = contestQuestionService.save(contestQuestion);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        long newContestQuestionId = contestQuestion.getId();
        return ResultUtils.success(newContestQuestionId);
    }

    /**
     * 删除竞赛题目关联
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteContestQuestion(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        // 判断是否存在
        ContestQuestion oldContestQuestion = contestQuestionService.getById(id);
        ThrowUtils.throwIf(oldContestQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        boolean b = contestQuestionService.removeById(id);
        return ResultUtils.success(b);
    }

    /**
     * 根据竞赛ID删除所有题目关联
     *
     * @param contestId
     * @param request
     * @return
     */
    @PostMapping("/delete/by-contest")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteByContestId(@RequestParam Long contestId, HttpServletRequest request) {
        if (contestId == null || contestId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = contestQuestionService.lambdaUpdate()
                .eq(ContestQuestion::getContestId, contestId)
                .remove();
        return ResultUtils.success(result);
    }

    /**
     * 根据题目ID删除所有竞赛关联
     *
     * @param questionId
     * @param request
     * @return
     */
    @PostMapping("/delete/by-question")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteByQuestionId(@RequestParam Long questionId, HttpServletRequest request) {
        if (questionId == null || questionId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = contestQuestionService.lambdaUpdate()
                .eq(ContestQuestion::getQuestionId, questionId)
                .remove();
        return ResultUtils.success(result);
    }

    /**
     * 更新竞赛题目关联
     *
     * @param contestQuestion
     * @param request
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateContestQuestion(@RequestBody ContestQuestion contestQuestion, HttpServletRequest request) {
        if (contestQuestion == null || contestQuestion.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 判断是否存在
        ContestQuestion oldContestQuestion = contestQuestionService.getById(contestQuestion.getId());
        ThrowUtils.throwIf(oldContestQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        boolean result = contestQuestionService.updateById(contestQuestion);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取竞赛题目关联
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    public BaseResponse<ContestQuestion> getContestQuestionById(long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        ContestQuestion contestQuestion = contestQuestionService.getById(id);
        if (contestQuestion == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        return ResultUtils.success(contestQuestion);
    }

    /**
     * 根据竞赛ID获取题目列表
     *
     * @param contestId
     * @param current
     * @param size
     * @return
     */
    @GetMapping("/list/by-contest")
    public BaseResponse<Page<ContestQuestion>> getQuestionsByContestId(
            @RequestParam Long contestId,
            @RequestParam(defaultValue = "1") long current,
            @RequestParam(defaultValue = "10") long size) {
        if (contestId == null || contestId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        Page<ContestQuestion> contestQuestionPage = contestQuestionService.lambdaQuery()
                .eq(ContestQuestion::getContestId, contestId)
                .orderByAsc(ContestQuestion::getQuestionOrder)
                .page(new Page<>(current, size));
        return ResultUtils.success(contestQuestionPage);
    }

    /**
     * 根据题目ID获取竞赛列表
     *
     * @param questionId
     * @param current
     * @param size
     * @return
     */
    @GetMapping("/list/by-question")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<ContestQuestion>> getContestsByQuestionId(
            @RequestParam Long questionId,
            @RequestParam(defaultValue = "1") long current,
            @RequestParam(defaultValue = "10") long size) {
        if (questionId == null || questionId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        Page<ContestQuestion> contestQuestionPage = contestQuestionService.lambdaQuery()
                .eq(ContestQuestion::getQuestionId, questionId)
                .orderByDesc(ContestQuestion::getCreateTime)
                .page(new Page<>(current, size));
        return ResultUtils.success(contestQuestionPage);
    }

    /**
     * 分页获取竞赛题目关联列表（仅管理员）
     *
     * @param current
     * @param size
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<ContestQuestion>> listContestQuestionByPage(@RequestParam long current, @RequestParam long size) {
        Page<ContestQuestion> contestQuestionPage = contestQuestionService.page(new Page<>(current, size));
        return ResultUtils.success(contestQuestionPage);
    }

    /**
     * 批量添加竞赛题目关联
     *
     * @param contestId
     * @param questionIds
     * @param request
     * @return
     */
    @PostMapping("/batch/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> batchAddContestQuestions(
            @RequestParam Long contestId,
            @RequestParam List<Long> questionIds,
            HttpServletRequest request) {
        if (contestId == null || contestId <= 0 || questionIds == null || questionIds.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        // 批量添加题目关联
        int displayOrder = 1;
        for (Long questionId : questionIds) {
            // 检查是否已存在
            ContestQuestion existingRelation = contestQuestionService.lambdaQuery()
                    .eq(ContestQuestion::getContestId, contestId)
                    .eq(ContestQuestion::getQuestionId, questionId)
                    .one();
            if (existingRelation == null) {
                ContestQuestion contestQuestion = new ContestQuestion();
                contestQuestion.setContestId(contestId);
                contestQuestion.setQuestionId(questionId);
                contestQuestion.setQuestionOrder(displayOrder++);
                contestQuestionService.save(contestQuestion);
            }
        }
        
        return ResultUtils.success(true);
    }

    /**
     * 更新题目显示顺序
     *
     * @param id
     * @param displayOrder
     * @param request
     * @return
     */
    @PostMapping("/update/order")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateQuestionOrder(
            @RequestParam Long id,
            @RequestParam Integer displayOrder,
            HttpServletRequest request) {
        if (id == null || id <= 0 || displayOrder == null || displayOrder < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        ContestQuestion contestQuestion = contestQuestionService.getById(id);
        ThrowUtils.throwIf(contestQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        
//        contestQuestion.setDisplay_order(displayOrder);
        boolean result = contestQuestionService.updateById(contestQuestion);
        return ResultUtils.success(result);
    }

    /**
     * 更新题目分值
     *
     * @param id
     * @param score
     * @param request
     * @return
     */
    @PostMapping("/update/score")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateQuestionScore(
            @RequestParam Long id,
            @RequestParam Integer score,
            HttpServletRequest request) {
        if (id == null || id <= 0 || score == null || score < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        ContestQuestion contestQuestion = contestQuestionService.getById(id);
        ThrowUtils.throwIf(contestQuestion == null, ErrorCode.NOT_FOUND_ERROR);
        
//        contestQuestion.setScore(score);
        boolean result = contestQuestionService.updateById(contestQuestion);
        return ResultUtils.success(result);
    }

    /**
     * 批量删除竞赛题目关联
     *
     * @param ids
     * @param request
     * @return
     */
    @PostMapping("/batch/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> batchDeleteContestQuestions(@RequestBody List<Long> ids, HttpServletRequest request) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = contestQuestionService.removeByIds(ids);
        return ResultUtils.success(result);
    }

    /**
     * 批量更新题目顺序
     *
     * @param contestQuestions
     * @param request
     * @return
     */
    @PostMapping("/batch/update-order")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> batchUpdateQuestionOrder(
            @RequestBody List<ContestQuestion> contestQuestions,
            HttpServletRequest request) {
        if (contestQuestions == null || contestQuestions.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        boolean result = contestQuestionService.updateBatchById(contestQuestions);
        return ResultUtils.success(result);
    }

    /**
     * 获取竞赛题目总数
     *
     * @param contestId
     * @return
     */
    @GetMapping("/count")
    public BaseResponse<Long> getQuestionCountByContestId(@RequestParam Long contestId) {
        if (contestId == null || contestId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        
        long count = contestQuestionService.lambdaQuery()
                .eq(ContestQuestion::getContestId, contestId)
                .count();
        
        return ResultUtils.success(count);
    }

}